package com.yorick.netty;

import com.yorick.netty.messageListener.Listener;
import com.yorick.netty.utils.ServerUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;

@Slf4j
public class WebSocketServerHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    @Resource
    private com.yorick.common.util.SpringTools SpringTools;

    public static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
        ByteBuf in = msg.content();
        byte[] data = new byte[2];
        in.readBytes(data);
        short msg_length = ServerUtil.byte2short(data);
        byte[] msg_id = new byte[4];
        in.readBytes(msg_id);
        int msg_id_int = ServerUtil.bytes2IntBig(msg_id);
        byte[] msg_body = new byte[msg_length];
        in.readBytes(msg_body);
        Listener listener = SpringTools.getApplicationContext().getBean(Listener.class);
        listener.getListener(String.valueOf(msg_id_int)).task(msg_body, ctx);
    }

    /**
     * 客户端连接的时候触发
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("新客户端连接：{}", ctx.channel().remoteAddress());
        channels.add(ctx.channel());
    }

    /**
     * 客户端断开连接的时候触发
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端退出了：{}", ctx.channel().remoteAddress());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //打印异常栈跟踪
        log.error(cause.getMessage());
        // 关闭该Channel
        ctx.close();
    }

    public void channelSend(Channel channel, int msg, byte[] body) {
        byte[] s_data = new byte[body.length + 6];
        byte[] s_id = ServerUtil.intToByteArray(msg);
        byte[] s_length = ServerUtil.short2Byte((short) body.length);
        System.arraycopy(s_length, 0, s_data, 0, s_length.length);
        System.arraycopy(s_id, 0, s_data, 2, s_id.length);
        System.arraycopy(body, 0, s_data, 6, body.length);
        ByteBuf resp = Unpooled.copiedBuffer(s_data);
        channel.writeAndFlush(new BinaryWebSocketFrame(resp));
    }

}
